//
// Created by chizuru on 2025/9/17.
//

#pragma once
#include "OperationResult.h"
#include "RetryPolicy.h"
#include "DeviceDecorator.h"
#include "IConnectable.h"
#include <iostream>
class ReconnectDecorator : public DeviceDecorator, public IConnectable {
public:
    ReconnectDecorator(std::shared_ptr<IDeviceIO> i, RetryPolicy rp = {})
            : DeviceDecorator(std::move(i)), rp(rp){
        connImpl = dynamic_cast<IConnectable*>(inner.get());
    }

    // IConnectable 接口实现
    OperationResult connect() override {
        if (!connImpl)
            return OperationResult::Fail(ErrorCode::Unsupported, "not connectable");
        return connImpl->connect();
    }
    OperationResult close() override {
        if (!connImpl)
            return OperationResult::Fail(ErrorCode::Unsupported, "not connectable");
        return connImpl->close();
    }
    bool isConnected() const override {
        return connImpl ? connImpl->isConnected() : true; // 非可连接设备视为始终可用
    }

    // 在写/读前确保连接
    int write(const char* data, size_t size) override {
        if (!ensureConnected())
            return -1; // 或返回特定错误码，DeviceComm 会把负值当 IO 错误处理
        return DeviceDecorator::write(data, size);
    }

    int read(char* buf, size_t maxSize) override {
        if (!ensureConnected())
            return -1;
        return DeviceDecorator::read(buf, maxSize);
    }

    int flushReadAndWrite() override {
        if (!ensureConnected())
            return -1;
        return DeviceDecorator::flushReadAndWrite();
    }

private:
    bool ensureConnected() {
        if (isConnected())
            return true;
        if (!connImpl)
            return true; // 非 connectable，认为可用

        return rp.withRetry([this](){
            return connImpl->connect().success;
        });
    }

    IConnectable* connImpl = nullptr;
    RetryPolicy rp;
};
